﻿using System;
using SharpKit.JavaScript;

namespace SharpKit.Onx
{
    /// <summary>
    /// RegionMonitor is the main component that encapsulates all the geo-fencing related operations. 
    /// Region's name is used as a unique key. Adding region with the same name will overwrite any existing region.
    /// https://www.onx.ms/#apiPage/regions
    /// </summary>
    [JsType(Mode = JsMode.Prototype, Export = false)]
    public class Regions : Emitter
    {
        //No way to new this up
        private Regions()
        { }

        #region Actions (Methods)
        /// <summary>
        /// Creates circular region to be monitored in the future. 
        /// To start monitoring pass it to startMonitoringForRegion method below This method should be invoked from JavaScript.
        /// </summary>
        /// <param name="args">The arguments for creating the region</param>
        /// <returns>The newly created region. null in case of parsing error.</returns>
        [JsMethod(Name = "createRegion")]
        public Region CreateRegion(CreateRegionArgs args)
        {
            return null;
        }

        /// <summary>
        /// Returns all monitored regions.
        /// </summary>
        /// <returns>collection of monitored regions</returns>
        [JsMethod(Name = "getall")]
        public Region[] Getall()
        {
            return null;
        }

        /// <summary>
        /// Returns monitored region by friendly name. 
        /// Note: if several regions with the same name exist the first one is returned 
        /// Note: this method has O(n) complexity. 
        /// Prefer using Region as a key.
        /// </summary>
        /// <param name="regionName">Region friendly name</param>
        /// <returns>monitored region or null if no regions with that name exist</returns>
        [JsMethod(Name = "getByName")]
        public Region GetByName(string regionName)
        {
            return null;
        }

        /// <summary>
        /// Checks whether the specified region is being monitored.
        /// </summary>
        /// <param name="region">The region to check for</param>
        /// <returns>whether the region is monitored</returns>
        [JsMethod(Name = "isMonitored")]
        public bool IsMonitored(Region region)
        {
            return false;
        }

        /// <summary>
        /// Checks whether the specified region is being monitored. 
        /// Note: if several regions with the same name exist the status of the first one is returned 
        /// Note: this method has O(n) complexity. 
        /// Prefer using Region as a key.
        /// </summary>
        /// <param name="regionName">Region friendly name</param>
        /// <returns>whether the region is monitored</returns>
        [JsMethod(Name = "isMonitoredByName")]
        public bool IsMonitoredByName(string regionName)
        {
            return false;
        }

        /// <summary>
        ///  Starts monitoring for the region.
        /// </summary>
        /// <param name="region">The region to monitor</param>
        [JsMethod(Name = "startMonitoring")]
        public void StartMonitoring(Region region)
        { }

        /// <summary>
        /// Stops monitoring for the region.
        /// </summary>
        /// <param name="region">The region to remove</param>
        [JsMethod(Name = "stopMonitoring")]
        public void StopMonitoring(Region region)
        { }

        /// <summary>
        /// Stops monitoring for all regions.
        /// </summary>
        [JsMethod(Name = "stopMonitoringAll")]
        public void StopMonitoringAll()
        { }
        #endregion

        #region Triggers (Events)
        /// <summary>
        /// trigger is received when the user enters the region. Additional trigger data is available in the GeofenceSignal parameter passed to the callback function.
        /// </summary>
        public event Action<GeofenceSignal> Enter
        {
            [JsMethod(Name = "on", InsertArg0 = "'enter'")]
            add
            {
            }
            [JsMethod(Name = "removeListener", InsertArg0 = "'enter'")]
            remove
            {
            }
        }

        /// <summary>
        /// trigger is received when the user exits the region. Additional trigger data is available in the GeofenceSignal parameter passed to the callback function.
        /// </summary>
        public event Action<GeofenceSignal> Exit
        {
            [JsMethod(Name = "on", InsertArg0 = "'exit'")]
            add
            {
            }
            [JsMethod(Name = "removeListener", InsertArg0 = "'exit'")]
            remove
            {
            }
        }
        #endregion
    }

    /// <summary>
    /// A geo-fencing event signal. For example, will be triggered when the user enters a specific region.
    /// </summary>
    [JsType(Mode = JsMode.Json, Export = false)]
    public class GeofenceSignal : ScriptSignal
    {
        /// <summary>
        /// Retrieves radius of the region which triggered this signal.
        /// </summary>
        [JsProperty(Name = "radius", NativeField = true)]
        public JsNumber Radius { get { return null; } }

        /// <summary>
        /// Retrieves the friendly name of the region which triggered this signal.
        /// </summary>
        [JsProperty(Name = "name", NativeField = true)]
        public string Name { get { return null; } }

        /// <summary>
        /// Retrieves the center longitude of the region which triggered this signal.
        /// </summary>
        [JsProperty(Name = "longitude", NativeField = true)]
        public JsNumber Longitude { get { return null; } }

        /// <summary>
        /// Retrieves the center latitude of the region which triggered this signal.
        /// </summary>
        [JsProperty(Name = "latitude", NativeField = true)]
        public JsNumber Latitude { get { return null; } }
    }

    /// <summary>
    /// The arguments for creating the region
    /// </summary>
    [JsType(JsMode.Json, Export = false)]
    public class CreateRegionArgs
    {
        /// <summary>
        /// String (can be null)
        /// </summary>
        [JsProperty(NativeField = true, Name = "name")]
        public string Name { get; set; }

        /// <summary>
        /// 
        /// </summary>
        [JsProperty(NativeField = true, Name = "latitude")]
        public double Latitude { get; set; }

        /// <summary>
        /// 
        /// </summary>
        [JsProperty(NativeField = true, Name = "longitude")]
        public double Longitude { get; set; }

        /// <summary>
        /// 
        /// </summary>
        [JsProperty(NativeField = true, Name = "radius")]
        public double Radius { get; set; }
    }

    /// <summary>
    /// TODO
    /// </summary>
    [JsType(JsMode.Prototype, Export = false)]
    public class Region
    {
        //No way to new this up
        private Region()
        {
        }
    }


}